package com.landun.market.web.controller;

import com.github.pagehelper.PageHelper;
import com.landun.market.exception.BusinessException;
import com.landun.market.pojo.enums.ResponseCode;
import com.landun.market.pojo.model.Category;
import com.landun.market.pojo.model.Price;
import com.landun.market.service.ICategoryService;
import com.landun.market.service.IPriceService;
import com.landun.market.util.CollectionUtils;
import com.landun.market.util.StringUtils;
import com.landun.market.web.PageableEntitiesConverter;
import com.landun.market.web.domain.ApiOut;
import com.landun.market.web.domain.PriceVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Created by yi.zhao on 2018/5/19.
 */
@Slf4j
@RestController
@RequestMapping("/prices")
public class PriceController extends AbstractController {
    @Autowired
    private IPriceService priceService;
    private ICategoryService categoryService;
    private final static String FILE_DATE_PATTERN = "yyyy-MM-dd";

    /**
     * 导入价格
     */
    @PostMapping(path = "/draft/import", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ApiOut<String> importPrices(@RequestParam("pricesExcel") MultipartFile multipartFile) {
        if (null == multipartFile) {
            throw new BusinessException("无法识别该表格，请检查格式并重新上传");
        }
        //获取文件名
        String fileName = multipartFile.getOriginalFilename();
        //进一步判断文件是否为空
        long size = multipartFile.getSize();
        if (StringUtils.isBlank(fileName) || size == 0) {
            throw new BusinessException("文件名或文件内容不可为空");
        }

        //判断是否是excel格式的文件
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            throw new BusinessException("非excel格式文件，不可上传");
        }
        //上传文件名称   2018-5-3.xlsx
        String dateStr = StringUtils.substringBefore(fileName, ".");
        Date priceDate = null;
        try {
            priceDate = DateUtils.parseDate(dateStr, FILE_DATE_PATTERN);
        } catch (Exception e) {
            throw new BusinessException("文件名称格式:yyyy-MM-dd");
        }
        try {
            priceService.importDraft(priceDate, multipartFile.getInputStream());
            return new ApiOut.Builder<String>().code(ResponseCode.SUCCESS).data(dateStr).build();
        } catch (Exception e) {
            throw new BusinessException("导入失败");
        }
    }

    /**
     * 导入价格
     */
    @PostMapping(path = "/draft/list", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ApiOut<List<PriceVO>> listDraftPrices(@RequestParam("date") String dateStr,
                                                 @RequestParam(value = "categoryId", required = false) Integer categoryId,
                                                 @RequestParam(name = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
                                                 @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
        Date priceDate = null;
        try {
            priceDate = DateUtils.parseDate(dateStr, FILE_DATE_PATTERN);
        } catch (Exception e) {
            throw new BusinessException(ResponseCode.PARAMETER_FORMAT_ERROR, "date");
        }

        PageHelper.startPage(pageIndex, pageSize);
        Category category = new Category();
        category.setId(categoryId);
        // 按统一格式返回数据
        return new ApiOut.Builder<List<PriceVO>>(true)
                .data(PageableEntitiesConverter.toVos(priceService.getDraft(priceDate, category), this::toVos))
                .build();
    }

    /**
     * 草稿发布
     */
    @PostMapping(path = "/draft/publish", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ApiOut<String> publishPrices(@RequestParam("date") String dateStr) {
        Date priceDate = null;
        try {
            priceDate = DateUtils.parseDate(dateStr, FILE_DATE_PATTERN);
        } catch (Exception e) {
            throw new BusinessException(ResponseCode.PARAMETER_FORMAT_ERROR, "date");
        }
        boolean result = priceService.publish(priceDate);
        ResponseCode code = result ? ResponseCode.SUCCESS : ResponseCode.SYSTEM_ERROR;
        return new ApiOut.Builder<String>().code(code).build();
    }

    /**
     * 草稿发布
     */
    @PutMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ApiOut<String> edit(@RequestBody PriceVO priceVO) {
        Price price = priceVO.toEntity();
        boolean result = priceService.update(price);
        ResponseCode code = result ? ResponseCode.SUCCESS : ResponseCode.SYSTEM_ERROR;
        return new ApiOut.Builder<String>().code(code).build();
    }


    private PriceVO toVo(Price user) {
        return Optional.ofNullable(user).map(PriceVO::new).orElse(null);
    }

    private List<PriceVO> toVos(List<Price> prices) {
        if (CollectionUtils.isEmpty(prices)) {
            return new ArrayList<>(0);
        }
        return prices.stream().map(this::toVo).filter(Objects::nonNull).collect(Collectors.toList());
    }
}
